//
//  EzFileSystem.cpp
//  ezLogin
//
//  Created by 刘跃龙 on 1/10/17.
//  Copyright © 2017 absolutemobile. All rights reserved.
//

#include "EzFileSystem.h"
#include <dirent.h> //DIR
#include <sys/stat.h> //S_IRWXU
#include "unistd.h" //access
#include <stdlib.h> //malloc
#include <stdio.h>
#include "FileUtils.h"
#include "cocos2d.h"
#include <fstream>
#include "ABMUtils.h"
#include "AccountData.h"

EZ_BEGIN
int umount_flag = 0;
LinuxLock m_lockUmountFlag;

void SD_umount_flag(int val)
{
    m_lockUmountFlag.Lock();
    umount_flag = val;
    m_lockUmountFlag.UnLock();
}
int getumount_flag(){
    AutoLinuxLock lock(&m_lockUmountFlag);
    return umount_flag;
}

//  ---------------------------
//  ==> File
//  ---------------------------
/** 创建目录 */
void makeDir(std::string dir)
{
    if (!checkIsFileExsit(dir)){
    mkdir(dir.c_str(),S_IRWXU);
    }
}
/** 检测文件是否存在 */
bool checkIsFileExsit(std::string fullpath)
{
    if (access(fullpath.c_str(), F_OK) == -1) {
        return false;
    }
    return true;
}
/** 文件重命名 */
int renameFile(std::string oldfilename,std::string newfilename)
{
    int ret = rename(oldfilename.c_str(),newfilename.c_str());
    return ret;
}
/** 替换文件内容 */
bool replaceFileString(std::string strInfo,std::string fullPath,long offset/* = 0*/)
{
    size_t size = strInfo.size();
    if(!(checkIsFileExsit(fullPath)))
    {
        return false;
    }
    if( fullPath.empty() || size == 0){
        return false;
    }
    do
    {
        FILE *fp = fopen(fullPath.c_str(), "wb+");
        if(!fp) break;
        fseek(fp,0,SEEK_END);
        size_t len = ftell(fp);
        if(offset < len) fseek(fp, 0, SEEK_SET);
        fwrite(strInfo.c_str(), size, 1, fp);
        fclose(fp);
        return true;
    } while (0);
    return false;
}
/** 写字符串到文件 */
bool writeStringToFile(std::string strInfo, std::string fullPath,bool append/* = false*/)
{
    size_t size = strInfo.size();
    const char* mode;
    if(append) mode = "wb+";
    else mode= "wb";
    
    if( fullPath.empty() || size == 0){
        return false;
    }
    
    do
    {
        FILE *fp = fopen(fullPath.c_str(), mode);
        if(!fp) break;
        fwrite(strInfo.c_str(), size, 1, fp);
        fclose(fp);
        return true;
    } while (0);
    return false;
}

/** 读字符串到文件 */
char* readStringFromFile(std::string fullpath,long offset/* = 0*/,long len/* = 0*/,long* totle/*= NULL*/,long* length)
{
    char* buffer = NULL;
    if (!fullpath.empty())
    {
        long size = 0;
        size_t readsize = 0;
        
        do{
            FILE *fp = fopen(fullpath.c_str(), "rb");
            if(!fp) break;
            fseek(fp,0,SEEK_END);
            size = ftell(fp);
            if(totle) *totle = size;
            if(0 == len) len = size-offset;
            if(size-offset < len) len = size-offset;
            if (0 == len) return NULL;
            fseek(fp,offset,SEEK_SET);
            buffer = (char*)malloc(sizeof(char) * len);
            if (NULL == buffer) return NULL;
            readsize = fread(buffer, sizeof(char), len, fp);
            if (0 == readsize) printf("Get data from file %s failed", fullpath.c_str());
            *length = readsize;
            fclose(fp);
        } while (0);
    }
    return buffer;
}
/** 删除文件 */
bool removeFile(std::string fullPath)
{
    const char* path = fullPath.c_str();
    if (remove(path) == 0) return true;
    else return false;
}

std::string getValueBySystemCommand(std::string strCommand){
    //printf("-----%s------\n",strCommand.c_str());
    std::string strData = "";
    FILE * fp = NULL;
    char buffer[128];
    fp=popen(strCommand.c_str(),"r");
    if (fp) {
        while(fgets(buffer,sizeof(buffer),fp)){
            strData.append(buffer);
        }
        pclose(fp);
    }
    //printf("-----%s------ end\n",strCommand.c_str());
    return strData;
}

std::string openFileByName(std::string strFullPath){
    FILE *fp;
    char buffer[128];
    fp = fopen(strFullPath.c_str(), "r");
    if(fp == NULL) {
        return "";
    }
    fscanf(fp, "%s", buffer);
    fclose(fp);
    return buffer;
}

bool writeFileByName(std::string strFullPath,std::string strData){
    std::fstream fs(strFullPath.c_str(),std::fstream::out|std::fstream::binary);
    fs.write(strData.c_str(),strData.size());
    fs.close();
    return true;
}

int runSystemCommand(std::string strCommand){
//    printf("-----%s------\n",strCommand.c_str());
    return system(strCommand.c_str());
}

bool checkIsHaveSDCard(){

    return false;
}

std::string checkNetworkStatus() {
    FILE *fp;
    char buffer[128];
    fp = fopen(CAMERA_NETSTATUS_PATH, "r");
    if(fp == NULL) {
        return "";
    }
    fscanf(fp, "%s", buffer);
    fclose(fp);
    return buffer;
}

uint32_t getSDStorageFileTime(){
    log("getSDStorageFileTime");
    std::string path = "/mnt/mmc/storage/";
    if(!checkIsFileExsit("/mnt/mmc/storage/")) return 0;
    
    DIR* pDir ;
    struct dirent* ent;
    pDir=opendir(path.c_str());
    std::string fileName= "";
    int cameraId = 0;
    uint32_t fileTime = 0;
    uint32_t lastTime = 0;
    while((ent=readdir(pDir))!=NULL)
    {
        if(ent->d_type != DT_REG) continue;//非普通文件不添加到列表
        fileName = ent->d_name;
        if (fileName.substr(fileName.size()-3) == ".fm") {
            fileName = fileName.substr(0,fileName.size()-3);
            std::vector<std::string> vecData = ABMUtils::split(fileName, "_");
            if (vecData.size()==2) {
                cameraId = atoi(vecData[0].c_str());
                fileTime = atoi(vecData[1].c_str());
                if (AccountData::getInstance()->getCameraInfo().iCameraId == cameraId) {
                    if (lastTime==0){
                        lastTime = fileTime;
                    }else if (lastTime > fileTime){
                        lastTime = fileTime;
                    }
                }
            }
        }
    }
    closedir(pDir);
    log("getSDStorageFileTime end");
    return lastTime;
}

/** 遍历目录 */
///*
// * File types
// */
//#define   DT_UNKNOWN   0          未知
//#define   DT_FIFO      1          管道或FIFO
//#define   DT_CHR       2          字符特殊文件
//#define   DT_DIR       4          目录文件
//#define   DT_BLK       6          块特殊文件
//#define   DT_REG       8          普通文件
//#define   DT_LNK      10          符号连接
//#define   DT_SOCK     12          套接字
//#define   DT_WHT      14
Ez::EzDir listDir(std::string path,int sort/* = 0*/,bool isAsc/* = true*/)
{
    if(path.substr(path.size()-1) != "/") path.append("/");
    Ez::EzFile file;
    int exists;
    
    Ez::EzDir ret;
    ret.list.clear();
    ret.path = path;
    ret.sort = 0;
    ret.size = 0;
    ret.isExist = checkIsFileExsit(path);
    if(!ret.isExist) return ret;
    
    DIR* pDir ;
    struct dirent* ent;
    pDir=opendir(path.c_str());
    while((ent=readdir(pDir))!=NULL)
    {
        if(ent->d_type != DT_REG) continue;//非普通文件不添加到列表
        file.name = ent->d_name;
        file.path = path + std::string(ent->d_name);
//        printf("[%d]%s\n",ent->d_type,ent->d_name);
        exists = stat(file.path.c_str(),&(file.status));
        if(exists<0) continue;//文件不存在
//        printf("[stat] size = %lld\n",file.status.st_size);
        ret.size += file.status.st_size;
        switch (sort) {
            case 1:
            {
                if(isAsc){
                    std::list<Ez::EzFile>::iterator it = ret.list.begin();
                    while(1)
                    {
                        if(it == ret.list.end()){
                            ret.list.push_back(file);
                            break;
                        }
                        if(file.status.st_mtime < it->status.st_mtime){
                            ret.list.insert(it, file);
                            break;
                        }else{
                            ++it;
                        }

                        
                    }
                }else{
                    std::list<Ez::EzFile>::iterator it = ret.list.begin();
                    while(1)
                    {
                        if(it == ret.list.end()){
                            ret.list.push_back(file);
                            break;
                        }
                        if(file.status.st_mtime > it->status.st_mtime){
                            ret.list.insert(it, file);
                            break;
                        }else{
                            ++it;
                        }
                        
                    }
                }
            }
                break;
            case 2:
            {
                if(isAsc){
                    std::list<Ez::EzFile>::iterator it = ret.list.begin();
                    while(1)
                    {
                        if(it == ret.list.end()){
                            ret.list.push_back(file);
                            break;
                        }
                        if(file.status.st_size < it->status.st_size){
                            ret.list.insert(it, file);
                            break;
                        }else{
                            ++it;
                        }
                        
                    }
                }else{
                    std::list<Ez::EzFile>::iterator it = ret.list.begin();
                    while(1)
                    {
                        if(it == ret.list.end()){
                            ret.list.push_back(file);
                            break;
                        }
                        if(file.status.st_size > it->status.st_size){
                            ret.list.insert(it, file);
                            break;
                        }else{
                            ++it;
                        }
                    }
                }
            }
                break;
            case 0:
            default:
                ret.list.push_back(file);
                break;
        }
    }
    closedir(pDir);
    return ret;
}

EZ_END
